﻿using System;
using System.Collections.Concurrent;
using System.Linq;

using RpcHelper.TaskTools;

namespace RpcHelper
{
    public class AutoResetDic
    {
        public static void AutoReset<TKey, TValue>(ConcurrentDictionary<TKey, TValue> dic, int resetTime = 180, int overTime = 300) where TValue : IDataSyncClass
        {
            TaskManage.AddTask(new AutoResetDic<TKey, TValue>(dic, new TimeSpan(0, 0, Tools.GetRandom(60, 90)), resetTime,overTime));
        }
    }
    internal class AutoResetDic<TKey, TValue> : ITask where TValue : IDataSyncClass
    {
        private readonly ConcurrentDictionary<TKey, TValue> _Dic = null;

        public string TaskId { get; set; }

        public int TaskPriority { get; set; } = 1;

        public string TaskName { get; set; } = "清理字典";

        public TaskType TaskType { get; set; } = TaskType.间隔任务;

        public TimeSpan ExecInterval { get; set; }
        public bool IsOnce { get; set; }
        private readonly int _OverTime;
        private readonly int _ResetTime;


        public AutoResetDic(ConcurrentDictionary<TKey, TValue> dic, TimeSpan time, int resetTime, int overTime)
        {
            this._ResetTime = resetTime;
            this._OverTime = overTime;
            this._Dic = dic;
            this.ExecInterval = time;
        }


        private void _Reset(TKey key)
        {
            if (this._Dic.TryGetValue(key, out TValue val))
            {
                val.ResetLock();
            }
        }

        public void ExecuteTask()
        {
            int now = HeartbeatTimeHelper.HeartbeatTime;
            int time = now - this._ResetTime;
            int overTime = now - this._OverTime;
            TKey[] keys = this._Dic.Where(a => a.Value.HeartbeatTime <= time || a.Value.ResetTime <= overTime).Select(a => a.Key).ToArray();
            if (keys.Length > 0)
            {
                keys.ForEach(a =>
                {
                    this._Reset(a);
                });
            }
        }

        public void Dispose()
        {

        }
        public void SetInterval(TimeSpan time)
        {
            this.ExecInterval = time;
        }
    }
}
